package drp.snowbell.io;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import drp.snowbell.storage.IStorage;
import drp.snowbell.storage.StorageManager;


/**
 * 用于把资源的数据写入到数据库
 * 
 * @author jimmy
 * 
 */
public class DbOutputStream extends OutputStream {

	private int index;
	private final static int CACHE_SIZE = 4 * 256;// 必须是4的倍数.因为int为4byte
	private List<Byte[]> cacheList = new ArrayList<Byte[]>();

	private Resource resource;

	public DbOutputStream(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void write(int b) throws IOException {
		Byte[] cache = null;
		if (index == 0) {
			cache = new Byte[CACHE_SIZE];
			cacheList.add(cache);
		} else {
			cache = cacheList.get(cacheList.size() - 1);
		}
		cache[index] = (byte) (b >>> 24);
		cache[index + 1] = (byte) (b >>> 16);
		cache[index + 2] = (byte) (b >>> 8);
		cache[index + 3] = (byte) b;
		index = index + 4;
		if (index >= CACHE_SIZE) {
			index = 0;
		}
	}

	@Override
	public void flush() throws IOException {
		// 保存到数据库 目前不支持blob
		int listSize = cacheList.size();
		if (listSize > 0) {
			int size = 0;
			for (int i = 0; i < listSize; i++) {
				if (i == listSize - 1) {
					// 最后一个缓存区 取index值
					if (index == 0) {
						// index=0 说明 size 为CACHE_SIZE
						size = size + CACHE_SIZE;
					} else {
						size = size + index;
					}
				} else {
					size = size + cacheList.get(i).length;
				}
			}
			byte[] bytes = new byte[size];
			int destPos = 0;
			for (int i = 0; i < listSize; i++) {
				Byte[] src = cacheList.get(i);
				int length = 0;
				if (i == listSize - 1) {
					if (index == 0) {
						length = CACHE_SIZE;
					} else {
						length = index;
					}
				} else {
					length = src.length;
				}
				System.arraycopy(src, 0, bytes, destPos, length);
				destPos = destPos + length;
			}
			cacheList.clear();
			index = 0;
			String text = new String(bytes);
			resource.setText(text);

			// 保存
			IStorage<Resource> storage = StorageManager.getCurrentStorage(Resource.class);
			storage.save(resource);
		}
	}

	@Override
	public void close() throws IOException {
		flush();
		super.close();
	}
}
